﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace nr.Tombola.Windows.Player
{
    public partial class MainForm : Form
    {
        private nr.Tombola.Net.GameClient client;
        private List<nr.Tombola.Controls.CardView> cards;

        private List<int> extract;

        public MainForm()
        {
            InitializeComponent();

            cards = new List<nr.Tombola.Controls.CardView>();
            extract = new List<int>();
            txtServerAddress.Text = "127.0.0.1";
            txtServerPort.Text = "9090";
        }

        private void AddCards(IEnumerable<nr.Tombola.Cards.Card> cardList)
        {
            foreach (nr.Tombola.Cards.Card c in cardList)
                cards.Add(new Controls.CardView() { Card = c });
            ShowCards();
        }

        private void ShowCards()
        {
            lbCards.Items.Clear();
            foreach (nr.Tombola.Controls.CardView c in cards)
                lbCards.Items.Add(c.Card);
        }

        private void PurgeCards()
        {
            foreach (nr.Tombola.Controls.CardView card in cards)
                card.Purge();
        }

        private void txtServerAddress_Validating(object sender, CancelEventArgs e)
        {
            try
            {
                System.Net.Dns.GetHostEntry(txtServerAddress.Text);
            }
            catch
            {
                txtServerAddress.SelectAll();
                e.Cancel = true;
            }
        }

        private void txtServerPort_Validating(object sender, CancelEventArgs e)
        {
            int value;
            if (int.TryParse(txtServerPort.Text, out value))
                e.Cancel = ((value < 1000) || (value > 9999));
            else
                e.Cancel = true;

            if (e.Cancel) txtServerPort.SelectAll();
        }

        private void miConnectionConnect_Click(object sender, EventArgs e)
        {
            try
            {
                client = new Net.GameClient(txtServerAddress.Text, int.Parse(txtServerPort.Text));
                client.NumberExtract += client_NumberExtract;
                client.StartGame += client_StartGame;
                client.EndGame += client_EndGame;
                client.GameStatus += client_GameStatus;
                client.Connect();
            }
            catch
            {
                MessageBox.Show(this, "Impossibile connettersi al server. Controllare che il server sia in esecuzione e l'indirizzo sia corretto.", "[nr.Tombola] Controller di Gioco", MessageBoxButtons.OK);
            }
        }

        void client_GameStatus(object sender,Net.GameStatusEventArgs e)
        {
            IAsyncResult r = BeginInvoke(new MethodInvoker(ClearNumbers));
            foreach (int number in e.Numbers)
                BeginInvoke(new UpdateNumbersDelegate(UpdateNumbers), number);
        }

        private void client_EndGame(object sender, Net.EndGameEventArgs e)
        {
            BeginInvoke(new MessageBoxDelegate(ShowMessage), "La partita è terminata.");
        }

        private void client_StartGame(object sender, Net.StartGameEventArgs e)
        {
            BeginInvoke(new MessageBoxDelegate(ShowMessage), "Inizia una nuova partita");
            BeginInvoke(new MethodInvoker(ClearNumbers));
        }

        private delegate void MessageBoxDelegate(string message);
        private delegate void UpdateNumbersDelegate(int number);

        private void ShowMessage(string message)
        {
            MessageBox.Show(this, message, "[nr.Tombola] Controller di Gioco", MessageBoxButtons.OK);
        }

        private void ClearNumbers()
        {
            PurgeCards();
            lbNumbers.Items.Clear();
        }

        private void UpdateNumbers(int number)
        {
            lbNumbers.Items.Insert(0, number.ToString());
        }

        private void client_NumberExtract(object sender, Net.NumberExtractEventArgs e)
        {
            extract.Add(e.Number);
            BeginInvoke(new UpdateNumbersDelegate(UpdateNumbers), e.Number);
            foreach (nr.Tombola.Controls.CardView card in cards)
                card.TurnNumber(e.Number, true);
        }

        private void ManageCards()
        {
            CardsManagerForm frm = new CardsManagerForm();
            List<nr.Tombola.Cards.Card> c = new List<Cards.Card>();
            foreach (nr.Tombola.Controls.CardView cv in cards) c.Add(cv.Card);
            frm.Cards = c;
            if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                cards = new List<Tombola.Controls.CardView>();
                AddCards(frm.Cards);
            }
        }

        private void miGameExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void lbCards_DoubleClick(object sender, EventArgs e)
        {
            CardViewForm frm =
                new CardViewForm()
                {
                    Card = (nr.Tombola.Cards.Card)lbCards.SelectedItem,
                    Numbers = extract.ToArray()
                };
            frm.Show();
        }

        private void miGameManageCards_Click(object sender, EventArgs e)
        {
            ManageCards();
        }
    }
}
